#include "lag.h"

/*
功能：窗口居中
参数：hWnd-窗口句柄
*/
void myCenterWindow(HWND hWnd)
{
	int screenWidth;		// 屏幕宽度
	int screenHeight;		// 屏幕高度
	RECT rect;				// 矩形

	// 得到屏幕尺寸
	screenWidth = GetSystemMetrics(SM_CXSCREEN);
	screenHeight = GetSystemMetrics(SM_CYSCREEN);

	// 得到窗口尺寸
	GetWindowRect(hWnd, &rect);

	// 重新设置窗口尺寸
	rect.left = (screenWidth - (rect.right - rect.left)) / 2;
	rect.top = (screenHeight - (rect.bottom - rect.top)) / 3;

	// 移动窗口到屏幕中间
	SetWindowPos(hWnd, HWND_TOP, rect.left, rect.top, rect.right, rect.bottom, SWP_NOSIZE);
}

/*
功能：得到某范围内的随机整数
参数：min - 最小值
	 max - 最大值
返回：某范围内的随机整数
备注：公式：min + rand() % (max - min + 1)
	 原理：rand() % m => 返回[0-m)的随机数
*/
int myRandom(int min, int max)
{
	// 生成随机种子（必须在原有毫秒时间的基础上再加随机值，否则在类似for循环中会出现同一种子值的现象）
	srand((unsigned int)time(NULL) + (unsigned)rand());

	return (int)(min + rand() % (max - min + 1));
}

/*
功能：定时器
参数：interval - 延时间隔（毫秒）
	 id - 编号 (0-max)
返回：true-已到时，false-未到时
*/
bool myTimer(int interval, int id)
{
	// 静态vector数组（默认数组元素为5，值为0）
	static vector<unsigned long long> vectorLastTimeForMyTimer(5, 0);

	// 根据编号自动扩容
	if (id < 0) { id = 0; }
	if ((int)vectorLastTimeForMyTimer.size() <= id) { vectorLastTimeForMyTimer.resize(id + 1, 0); }

	// 得到当前毫秒并判断是否到时
	unsigned long long currentTime = GetTickCount64();
	if (vectorLastTimeForMyTimer[id] == 0)		// 未初始化呢
	{
		vectorLastTimeForMyTimer[id] = currentTime;
		return false;
	}
	else
	{
		int addTime = (int)(currentTime - vectorLastTimeForMyTimer[id]);
		if (addTime >= interval)
		{
			vectorLastTimeForMyTimer[id] = currentTime;
			return true;
		}
	}

	return false;
}

/*
功能：播放音频
参数：fileName - 音频文件
	 repeat - 是否循环播放（true-循环，false-不循环）
返回：无
*/
void myPlayAudio(const string& fileName, bool repeat)
{
	string command = "play " + fileName;
	if (repeat) { command += " repeat"; }
	mciSendString(command.c_str(), 0, 0, 0);
}

/*
功能：判断某键是否被按下
参数：keyCode - 键值
返回：true-按下，false-未按下
*/
bool myKeyDown(int keyCode)
{
	return (GetAsyncKeyState(keyCode) & 0x8000);
}

/*
功能：判断两个矩形是否相交
参数：x1 - 第一个矩形的左上角X坐标
	 y1 - 第一个矩形的左上角Y坐标
	 w1 - 第一个矩形的宽度
	 h1 - 第一个矩形的高度
	 x2 - 第二个矩形的左上角X坐标
	 y2 - 第二个矩形的左上角Y坐标
	 w2 - 第二个矩形的宽度
	 h2 - 第二个矩形的高度
返回：true-相交，false-不相交
*/
bool myRectIntersectRect(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)
{
	if (x1 > x2 + w2) { return false; }
	if (x2 > x1 + w1) { return false; }
	if (y1 > y2 + h2) { return false; }
	if (y2 > y1 + h1) { return false; }

	return true;
}

/*
功能：载入图片并过滤透明部分（做位运算）
参数：picture_x - 载入图片X坐标
	 picture_y - 载入图片Y坐标
	 picture - 载入图片
返回：无
*/
void myDrawImageAlpha(int  picture_x, int picture_y, IMAGE* picture)
{
	DWORD* dst = GetImageBuffer();						// GetImageBuffer()函数，用于获取绘图设备的显存指针，EASYX自带
	DWORD* draw = GetImageBuffer();
	DWORD* src = GetImageBuffer(picture);				// 获取picture的显存指针
	int picture_width = picture->getwidth();			// 获取picture的宽度，EASYX自带
	int picture_height = picture->getheight();			// 获取picture的高度，EASYX自带
	int graphWidth = getwidth();						// 获取绘图区的宽度，EASYX自带
	int graphHeight = getheight();						// 获取绘图区的高度，EASYX自带
	int dstX = 0;										// 在显存里像素的角标

	// 实现透明贴图 公式： Cp=αp*FP+(1-αp)*BP ， 贝叶斯定理来进行点颜色的概率计算
	for (int iy = 0; iy < picture_height; iy++)
	{
		for (int ix = 0; ix < picture_width; ix++)
		{
			int srcX = ix + iy * picture_width;			// 在显存里像素的角标
			int sa = ((src[srcX] & 0xff000000) >> 24);	// 0xAArrggbb;AA是透明度
			int sr = ((src[srcX] & 0xff0000) >> 16);	// 获取RGB里的R
			int sg = ((src[srcX] & 0xff00) >> 8);		// G
			int sb = src[srcX] & 0xff;					// B
			if (ix >= 0 && ix <= graphWidth && iy >= 0 && iy <= graphHeight && dstX <= graphWidth * graphHeight)
			{
				dstX = (ix + picture_x) + (iy + picture_y) * graphWidth;		// 在显存里像素的角标
				int dr = ((dst[dstX] & 0xff0000) >> 16);
				int dg = ((dst[dstX] & 0xff00) >> 8);
				int db = dst[dstX] & 0xff;
				draw[dstX] = ((sr * sa / 255 + dr * (255 - sa) / 255) << 16)	// 公式： Cp=αp*FP+(1-αp)*BP  ； αp=sa/255 , FP=sr , BP=dr
					| ((sg * sa / 255 + dg * (255 - sa) / 255) << 8)			// αp=sa/255 , FP=sg , BP=dg
					| (sb * sa / 255 + db * (255 - sa) / 255);					// αp=sa/255 , FP=sb , BP=db
			}
		}
	}
}

/*
功能：绘制透明图片
参数：dstX - 目的X坐标
	 dstY - 目的Y坐标
	 pSrcImg - 源图像指针
	 winWidth - 窗口宽度（判断图片位置是否超出窗口范围，不录则默认为0，表示该参数不用）
	 winHeight - 窗口高度（判断图片位置是否超出窗口范围，不录则默认为0，表示该参数不用）
返回：无
*/
void myDrawImage(int dstX, int dstY, IMAGE* pSrcImg, int winWidth, int winHeight)
{
	IMAGE imgTmp;
	int newImgX = 0;
	int newImgY = 0;
	int newImgWidth = pSrcImg->getwidth();
	int newImgHeight = pSrcImg->getheight();
	int flag = 0;

	// 图片完全不在窗口中
	if (dstX <= -pSrcImg->getwidth()) { return; }
	if (winWidth > 0 && dstX >= winWidth) { return; }
	if (dstY <= -pSrcImg->getheight()) { return; }
	if (winHeight > 0 && dstY >= winHeight) { return; }

	// 处理X坐标
	if (dstX < 0)   // 左边界
	{
		newImgX = -dstX;
		newImgWidth = pSrcImg->getwidth() + dstX;
		dstX = 0;
		flag = 1;
	}
	else if (winWidth > 0 && dstX > winWidth - pSrcImg->getwidth())     // 右边界
	{
		newImgWidth = winWidth - dstX;
		flag = 1;
	}

	// 处理Y坐标
	if (dstY < 0)       // 上边界
	{
		newImgY = -dstY;
		newImgHeight = pSrcImg->getheight() + dstY;
		dstY = 0;
		flag = 1;
	}
	else if (winHeight > 0 && dstY > winHeight - pSrcImg->getheight())      // 下边界
	{
		newImgHeight = winHeight - dstY;
		flag = 1;
	}

	// 处理图片变动
	if (flag == 1)
	{
		SetWorkingImage(pSrcImg);   // 设定pSrcImg为当前的绘图设备
		getimage(&imgTmp, newImgX, newImgY, newImgWidth, newImgHeight);      // 从当前绘图设备获取图像（即截取pSrcImg的要显示部分内容放到imgTmp中）
		SetWorkingImage();          // 恢复默认绘图设备
		pSrcImg = &imgTmp;
	}

	// 开始输出透明位图
	myDrawImageAlpha(dstX, dstY, pSrcImg);
}

/*
功能：绘制字符串
参数：text - 字符串内容
	 x - X坐标
	 y - Y坐标
返回：无
*/
void myDrawString(int x, int y, const string& text)
{
	outtextxy(x, y, text.c_str());
}

/*
功能：绘制血条
参数：x - 血条X坐标
	 y - 血条Y坐标
	 width - 血条宽度
	 height - 血条高度
	 percent - 血条比例
返回：无
*/
void myDrawBloodBar(int x, int y, int width, int height, float percent);

/*
功能：绘制血条
参数：x - 血条X坐标
	 y - 血条Y坐标
	 width - 血条宽度
	 height - 血条高度
	 percent - 血条比例
返回：无
*/
void myDrawBloodBar(int x, int y, int width, int height, float percent)
{
	// 记录原来的状态，以便后面恢复
	COLORREF fillColor = getfillcolor();
	COLORREF getColor = getcolor();

	if (percent < 0) { percent = 0.0; }

	setfillcolor(YELLOW);
	solidrectangle(x, y, x + width, y + height);
	setfillcolor(RED);
	solidrectangle(x, y, (int)(x + width * percent), y + height);
	setcolor(WHITE);
	rectangle(x, y, x + width, y + height);

	// 恢复原来的状态
	setfillcolor(fillColor);
	setcolor(getColor);
}